﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using System.Threading;
using System.Net;
using cb0tServer;

namespace sb0t_winGUI
{
    public partial class Quiz : Form
    {
        private static QuizItem[] current_list;

        internal static QuizItem[] CurrentList
        {
            get
            {
                return current_list == null ? new QuizItem[] { } : current_list;
            }
        }

        private bool drag = false;
        private Point pos = new Point();
        private Thread thread;

        public Quiz()
        {
            InitializeComponent();

            if (!Directory.Exists(RunOnceFileUpdater.sbotpath + "quiz"))
                Directory.CreateDirectory(RunOnceFileUpdater.sbotpath + "quiz");

            this.button2_Click(null, new EventArgs());

            try
            {
                String filename = CoreSettings.last_quiz;
                List<QuizItem> items = new List<QuizItem>();

                if (filename.Length > 0)
                {
                    FileStream f = new FileStream(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "quiz/" + filename + ".quiz", FileMode.Open);
                    XmlReader xml = XmlReader.Create(new StreamReader(f));

                    xml.MoveToContent();
                    xml.ReadSubtree().ReadToFollowing("quiz");

                    while (xml.ReadToFollowing("item"))
                    {
                        QuizItem x = new QuizItem();

                        xml.ReadSubtree().ReadToFollowing("question");
                        x.Question = Encoding.UTF8.GetString(Convert.FromBase64String(xml.ReadElementContentAsString())).Trim();
                        xml.ReadToFollowing("answer");
                        x.Answer = Encoding.UTF8.GetString(Convert.FromBase64String(xml.ReadElementContentAsString())).Trim();

                        if (x.Question.Length > 0 && x.Answer.Length > 0)
                            items.Add(x);
                    }

                    xml.Close();
                    f.Flush();
                    f.Close();

                    if (items.Count > 0)
                    {
                        this.textBox1.Text = filename;
                        this.dataGridView1.Rows.Clear();

                        foreach (QuizItem x in items)
                            this.dataGridView1.Rows.Add(new String[] { x.Question, x.Answer });

                        current_list = items.ToArray();
                    }
                }
            }
            catch { }

        }

        private void listBox1_MouseDoubleClick(object sender, MouseEventArgs e) // change quiz set
        {
            if (this.listBox1.SelectedIndex > this.listBox1.Items.Count || this.listBox1.SelectedIndex < 0)
                return;

            try
            {
                String filename = (String)this.listBox1.Items[this.listBox1.SelectedIndex];
                List<QuizItem> items = new List<QuizItem>();
                
                FileStream f = new FileStream(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "quiz/" + filename + ".quiz", FileMode.Open);
                XmlReader xml = XmlReader.Create(new StreamReader(f));

                xml.MoveToContent();
                xml.ReadSubtree().ReadToFollowing("quiz");

                while (xml.ReadToFollowing("item"))
                {
                    QuizItem x = new QuizItem();

                    xml.ReadSubtree().ReadToFollowing("question");
                    x.Question = Encoding.UTF8.GetString(Convert.FromBase64String(xml.ReadElementContentAsString())).Trim();
                    xml.ReadToFollowing("answer");
                    x.Answer = Encoding.UTF8.GetString(Convert.FromBase64String(xml.ReadElementContentAsString())).Trim();

                    if (x.Question.Length > 0 && x.Answer.Length > 0)
                        items.Add(x);
                }

                xml.Close();
                f.Flush();
                f.Close();

                if (items.Count > 0)
                {
                    this.textBox1.Text = filename;
                    this.dataGridView1.Rows.Clear();

                    foreach (QuizItem x in items)
                        this.dataGridView1.Rows.Add(new String[] { x.Question, x.Answer });

                    current_list = items.ToArray();
                    CoreSettings.last_quiz = filename;
                    CoreSettings.SaveNew();
                }
            }
            catch { }
        }

        private void button2_Click(object sender, EventArgs e) // refresh quiz list
        {
            try
            {
                String folder = RunOnceFileUpdater.sbotpath + "quiz";
                String[] files = Directory.GetFiles(folder);
                files = new List<String>(files).FindAll(x => x.EndsWith(".quiz")).ToArray();
                this.listBox1.Items.Clear();

                foreach (String str in files)
                {
                    FileInfo fi = new FileInfo(str);
                    this.listBox1.Items.Add(fi.Name.Substring(0, fi.Name.Length - 5));
                }
            }
            catch { }

            if (this.listBox1.Items.Count == 0)
                this.textBox1.Text = "default";
        }

        private void button1_Click(object sender, EventArgs e) // save quiz set
        {
            List<QuizItem> items = new List<QuizItem>();

            for (int i = 0; i < this.dataGridView1.Rows.Count; i++)
            {
                String q = (String)this.dataGridView1.Rows[i].Cells[0].Value;
                String a = (String)this.dataGridView1.Rows[i].Cells[1].Value;

                if (String.IsNullOrEmpty(q) || String.IsNullOrEmpty(a))
                    continue;

                q = q.Trim();
                a = a.Trim();

                if (q.Length > 0 && a.Length > 0)
                    items.Add(new QuizItem(q, a));
            }

            this.dataGridView1.Rows.Clear();

            foreach (QuizItem i in items)
                this.dataGridView1.Rows.Add(new String[] { i.Question, i.Answer });

            if (items.Count == 0)
                return;

            String filename = this.textBox1.Text.Trim();
            String[] illegals = new String[] { "/", "?", "<", ">", "\\", ":", "*", "|", "\"", "^", "." };

            for (int i = 0; i < illegals.Length; i++)
                filename = filename.Replace(illegals[i], "");

            if (filename.Length < 2)
                filename = "default";

            this.textBox1.Text = filename;

            try
            {
                XmlWriterSettings appearance = new XmlWriterSettings();
                appearance.Indent = true;
                XmlWriter xml = XmlWriter.Create(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "quiz/" + filename + ".quiz", appearance);

                xml.WriteStartDocument();
                xml.WriteStartElement("quiz");

                foreach (QuizItem x in items)
                {
                    xml.WriteStartElement("item");
                    xml.WriteElementString("question", Convert.ToBase64String(Encoding.UTF8.GetBytes(x.Question)));
                    xml.WriteElementString("answer", Convert.ToBase64String(Encoding.UTF8.GetBytes(x.Answer)));
                    xml.WriteEndElement();
                }

                xml.WriteEndElement();
                xml.WriteEndDocument();
                xml.Flush();
                xml.Close();
            }
            catch { }

            current_list = items.ToArray();
            this.button2_Click(null, new EventArgs());
        }

        private void button3_Click(object sender, EventArgs e) // close form
        {
            this.Hide();
        }

        protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs e)
        {
            base.OnPaintBackground(e);

            Graphics g = e.Graphics;
            Rectangle r = new Rectangle(0, 0, this.Width, this.Height);

            for (int i = 2; i < 10; i++)
            {
                g.DrawRectangle(new Pen(Color.FromArgb((i * 25), (i * 25), (i * 25)), 1), r);
                r = new Rectangle(i - 2, i - 2, this.Width - (2 * (i - 2)), this.Height - (2 * (i - 2)));
            }

            LinearGradientBrush l = new LinearGradientBrush(r,
                Color.FromArgb(210, 210, 210),
                Color.FromArgb(255, 255, 255),
                45f);

            g.FillRectangle(l, r);

            g.DrawLine(new Pen(Brushes.DarkGray, 2), new Point(6, 32), new Point(this.Width - 5, 32));

            r = new Rectangle(6, 7, this.Width - 12, 24);
            g.FillRectangle(Brushes.LightGray, r);

            Font f = new System.Drawing.Font("Verdana", 10F, System.Drawing.FontStyle.Regular,
                System.Drawing.GraphicsUnit.Point, ((byte)(0)));

            g.DrawString("Quiz Editor", f, Brushes.Black, new PointF(10, 10));

            l.Dispose();

            this.Opacity = 0.90;
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            if (this.drag)
            {
                Point p1 = new Point(e.X, e.Y);
                Point p2 = this.PointToScreen(p1);
                Point p3 = new Point(p2.X - this.pos.X,
                                     p2.Y - this.pos.Y);
                this.Location = p3;
            }
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);

            this.drag = false;
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);

            if (e.X >= 6 && e.X <= (this.Width - 7))
            {
                if (e.Y >= 6 && e.Y <= 32)
                {
                    this.drag = true;
                    this.pos = new Point(e.X, e.Y);
                }
            }
        }

        private void deleteItemToolStripMenuItem_Click(object sender, EventArgs e) // remove row
        {
            if (this.dataGridView1.SelectedCells.Count > 0)
                if (this.dataGridView1.SelectedCells[0].RowIndex < (this.dataGridView1.Rows.Count - 1))
                    this.dataGridView1.Rows.RemoveAt(this.dataGridView1.SelectedCells[0].RowIndex);
        }

        private void deleteItemToolStripMenuItem1_Click(object sender, EventArgs e) // remove file
        {
            if (this.listBox1.SelectedIndex > this.listBox1.Items.Count || this.listBox1.SelectedIndex < 0)
                return;

            try
            {
                String filename = (String)this.listBox1.Items[this.listBox1.SelectedIndex];
                File.Delete(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "quiz/" + filename + ".quiz");
            }
            catch { }

            this.button2_Click(null, new EventArgs());
        }

        private void button4_Click(object sender, EventArgs e)
        {
            this.textBox1.Text = "default";
            this.dataGridView1.Rows.Clear();
        }

        private void button5_Click(object sender, EventArgs e) // download questions
        {
            this.textBox1.Text = "";
            this.dataGridView1.Rows.Clear();
            this.Enabled = false;
            this.thread = new Thread(new ThreadStart(this.DownloadQuestions));
            this.thread.Start();
        }

        private void DownloadQuestions()
        {
            try
            {
                String[] catagories = new String[]
                {
                    "General",
                    "Science",
                    "History",
                    "Geography",
                    "Music",
                    "Movies",
                    "Sports",
                    "Literature"
                };

                HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.triviaquizgenerator.com/PrintableTriviaQuestions.php");
                byte[] data = Encoding.Default.GetBytes("quizrequest=1&title=&category=" + catagories[(int)Math.Floor(Helpers.rnd.NextDouble() * 8)] + "&questionNum=+25&quizType=Text&numberQuestions=No&answerLocation=Under&submit=Generate+Quiz");
                request.Method = "post";
                request.ContentType = "application/x-www-form-urlencoded";
                request.ContentLength = data.Length;
                Stream stream = request.GetRequestStream();
                stream.Write(data, 0, data.Length);
                stream.Flush();
                stream.Close();
                WebResponse response = request.GetResponse();
                stream = response.GetResponseStream();
                StreamReader reader = new StreamReader(stream);
                int counter = 0;
                List<QuizItem> items = new List<QuizItem>();

                while (!reader.EndOfStream)
                {
                    String str = reader.ReadLine();

                    if (str.Contains("<textarea readonly name"))
                    {
                        while (!reader.EndOfStream)
                        {
                            QuizItem q = new QuizItem();
                            q.Question = reader.ReadLine().Trim();

                            if (q.Question.Length > 0)
                            {
                                q.Answer = reader.ReadLine();

                                if (q.Answer.IndexOf(" -") > -1)
                                    q.Answer = q.Answer.Substring(0, q.Answer.IndexOf(" -"));

                                Regex re = new Regex(@"\(.*?\)", RegexOptions.IgnoreCase);
                                q.Answer = re.Replace(q.Answer, "");
                                q.Answer = q.Answer.Replace(".", "");
                                q.Answer = q.Answer.Replace(",", "");
                                q.Answer = q.Answer.Replace(".", "");
                                q.Answer = q.Answer.Replace("?", "");
                                q.Answer = q.Answer.Replace("'", "");
                                q.Answer = q.Answer.Replace("\"", "");
                                q.Answer = q.Answer.Replace("!", "");

                                while (q.Answer.Contains("  "))
                                    q.Answer = q.Answer.Replace("  ", " ");

                                q.Answer = q.Answer.Trim();

                                if (q.Answer.Length > 0 && q.Answer.Length <= 20)
                                    items.Add(q);

                                if (++counter >= 25)
                                    break;
                            }
                        }
                    }
                }

                stream.Flush();
                stream.Close();

                if (items.Count == 0)
                    throw new Exception("no questions were found");

                current_list = items.ToArray();
                this.EnableQuizForm();
                Thread.Sleep(500);
                this.PopulateDownloadQuiz();
                return;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
                this.EnableQuizForm();
            }
        }

        private delegate void EnableQuizFormDelegate();
        private void EnableQuizForm()
        {
            if (this.InvokeRequired)
                this.BeginInvoke(new EnableQuizFormDelegate(this.EnableQuizForm));
            else
                this.Enabled = true;
        }
        
        private delegate void PopulateDownloadQuizDelegate();
        private void PopulateDownloadQuiz()
        {
            if (this.dataGridView1.InvokeRequired)
            {
                this.dataGridView1.BeginInvoke(new PopulateDownloadQuizDelegate(this.PopulateDownloadQuiz));
            }
            else
            {
                for (int i = 0; i < current_list.Length; i++)
                    this.dataGridView1.Rows.Add(new String[] { current_list[i].Question, current_list[i].Answer });
            }
        }
    }

    class QuizItem
    {
        public String Question;
        public String Answer;

        public QuizItem() { }

        public QuizItem(String Question, String Answer)
        {
            this.Question = Question;
            this.Answer = Answer;
        }
    }
}
